package imp

import (
	sqlc "bgs/db/sqlc"
	userFollowGrpc "bgs/grpc/gen/service/user_follow"
	"bgs/grpc/gen/shared/message"
	"context"
)

/****************************************************************************************/
/*                               user_follow entity of helper                           */
/****************************************************************************************/


func transformUserFollowEntityToPb(userFollow sqlc.UserFollow) *userFollowGrpc.UserFollowEntity {
	return &userFollowGrpc.UserFollowEntity{
		Id:             userFollow.ID,
		UserId:         userFollow.UserID,
		FollowedUserId: userFollow.FollowedUserID,
		Followed:     sqlc.GoTimeToPBTimestamp(userFollow.Followed),
		Remark:         userFollow.Remark.String,
	}
}

/****************************************************************************************/
/*                               user_follow entity of cmd                              */
/****************************************************************************************/

// UpsertUserFollow 创建用户关注关系
func (s *UserAPIService) UpsertUserFollow(ctx context.Context, req *userFollowGrpc.UpsertUserFollowRequest) (res *userFollowGrpc.UpsertUserFollowResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("user_followImp->UpsertUserFollow:%v", req)
	res = &userFollowGrpc.UpsertUserFollowResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	arg := sqlc.UpsertUserFollowParams{
		UserID:         req.UserId,
		FollowedUserID: req.FollowedUserId,
		Followed:     sqlc.PBTimestampToGoTime(req.Followed),
	}
	userFollow, err := s.dao.Q.UpsertUserFollow(ctx, arg)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.UserFollow = transformUserFollowEntityToPb(userFollow)
	return
}

// UpdateUserFollow 更新用户关注关系
func (s *UserAPIService) UpdateUserFollow(ctx context.Context, req *userFollowGrpc.UpdateUserFollowRequest) (res *userFollowGrpc.UpdateUserFollowResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("user_followImp->UpdateUserFollow:%v", req)
	res = &userFollowGrpc.UpdateUserFollowResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	arg := sqlc.UpdateUserFollowParams{
		ID:        req.Id,
		Remark:    sqlc.NSFromString(req.Remark),
	}
	userFollow, err := s.dao.Q.UpdateUserFollow(ctx, arg)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.UserFollow = transformUserFollowEntityToPb(userFollow)
	return
}

/****************************************************************************************/
/*                               user_follow entity of query                            */
/****************************************************************************************/

// GetUserFollow 获取单个用户关注
func (s *UserAPIService) GetUserFollow(ctx context.Context, req *userFollowGrpc.GetUserFollowRequest) (res *userFollowGrpc.GetUserFollowResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("user_followImp->GetUserFollow:%v", req)
	res = &userFollowGrpc.GetUserFollowResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	userFollow, err := s.dao.Q.GetUserFollow(ctx, req.Id)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.UserFollow = transformUserFollowEntityToPb(userFollow)
	return
}

/****************************************************************************************/
/*                            user_followJoins entity of helper                            */
/****************************************************************************************/

func transformUserFollowWithUserAndUserStatEntityToPb(row sqlc.ListUserFollowWithUserAndUserStatsRow) *userFollowGrpc.UserFollowWithUserAndUserStatEntity {
	return &userFollowGrpc.UserFollowWithUserAndUserStatEntity{
		// user_follow
		Id:          row.ID,
		UserId: row.UserID,
		FollowedUserId:  row.FollowedUserID,
		Followed:    sqlc.GoTimeToPBTimestamp( row.Followed),
		Remark:      row.Remark.String,

		// user
		FollowedUserName: row.NickName,
		FollowedUserPic: row.Pic,

		// user_stat
		FansCount:            row.FansCount,
		FollowUserCount:      row.FollowUserCount,
		FollowBrandCount:     row.FollowBrandCount,
		EndorseBrandCount:    row.EndorseBrandCount,
		EndorseActivityCount: row.EndorseActivityCount,
		InvolveActivityCount: row.InvolveActivityCount,
		OrderCount:           row.OrderCount,
		ViewCount:            row.ViewCount,
		PayAmount:            row.PayAmount,
	}
}

func mapUserFollowWithUserAndUserStatEntityToPb(list []sqlc.ListUserFollowWithUserAndUserStatsRow, f func(sqlc.ListUserFollowWithUserAndUserStatsRow) *userFollowGrpc.UserFollowWithUserAndUserStatEntity) []*userFollowGrpc.UserFollowWithUserAndUserStatEntity {
	r := make([]*userFollowGrpc.UserFollowWithUserAndUserStatEntity, len(list))
	for i, item := range list {
		r[i] = f(item)
	}
	return r
}

/****************************************************************************************/
/*                            user_followJoins entity of query                             */
/****************************************************************************************/

// ListUserFollowWithUserAndUserStats  获取关注的用户及其统计信息
func (s *UserAPIService) ListUserFollowWithUserAndUserStats(ctx context.Context, req *userFollowGrpc.ListUserFollowWithUserAndUserStatsRequest) (res *userFollowGrpc.ListUserFollowWithUserAndUserStatsResponse, err error) {
	slog := s.NewContextLogger(ctx)
	slog.Infof("user_followImp->ListUserFollowWithUserAndUserStats:%v", req)

	res = &userFollowGrpc.ListUserFollowWithUserAndUserStatsResponse{
		OpRet: &message.OperationResult{
			Success: true,
			Code:    0,
		},
	}
	total, err := s.dao.Q.CountUserFollowWithUserAndUserStats(ctx, req.UserId)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	if total == 0 {
		// 不用继续调用listfunc
		return
	}
	arg := sqlc.ListUserFollowWithUserAndUserStatsParams{
		Limit:       req.Limit,
		Offset:      req.Offset,
		UserID: req.UserId,
	}
	userFollowWithUserAndUserStats, err := s.dao.Q.ListUserFollowWithUserAndUserStats(ctx, arg)
	if err != nil {
		res.OpRet = &message.OperationResult{
			Success: false,
			Code:    400,
			Msg:     err.Error(),
		}
		return
	}
	res.Total = total
	res.UserFollowWithUserAndUserStats = mapUserFollowWithUserAndUserStatEntityToPb(userFollowWithUserAndUserStats, transformUserFollowWithUserAndUserStatEntityToPb)
	return
}
